﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Terraria.ModLoader.IO;

namespace Terraria.ModLoader
{
	// Token: 0x02000180 RID: 384
	internal class BuildProperties
	{
		// Token: 0x06000F5B RID: 3931 RVA: 0x004026B0 File Offset: 0x004008B0
		public IEnumerable<BuildProperties.ModReference> Refs(bool includeWeak)
		{
			if (!includeWeak)
			{
				return this.modReferences;
			}
			return this.modReferences.Concat(this.weakReferences);
		}

		// Token: 0x06000F5C RID: 3932 RVA: 0x0000E6BF File Offset: 0x0000C8BF
		public IEnumerable<string> RefNames(bool includeWeak)
		{
			return from dep in this.Refs(includeWeak)
			select dep.mod;
		}

		// Token: 0x06000F5D RID: 3933 RVA: 0x004026DC File Offset: 0x004008DC
		private static IEnumerable<string> ReadList(string value)
		{
			return from s in value.Split(new char[]
			{
				','
			})
			select s.Trim() into s
			where s.Length > 0
			select s;
		}

		// Token: 0x06000F5E RID: 3934 RVA: 0x00402744 File Offset: 0x00400944
		private static IEnumerable<string> ReadList(BinaryReader reader)
		{
			List<string> list = new List<string>();
			string text = reader.ReadString();
			while (text.Length > 0)
			{
				list.Add(text);
				text = reader.ReadString();
			}
			return list;
		}

		// Token: 0x06000F5F RID: 3935 RVA: 0x00402778 File Offset: 0x00400978
		private static void WriteList<T>(IEnumerable<T> list, BinaryWriter writer)
		{
			foreach (T t in list)
			{
				writer.Write(t.ToString());
			}
			writer.Write("");
		}

		// Token: 0x06000F60 RID: 3936 RVA: 0x004027D8 File Offset: 0x004009D8
		internal static BuildProperties ReadBuildFile(string modDir)
		{
			string path = modDir + Path.DirectorySeparatorChar.ToString() + "build.txt";
			string path2 = modDir + Path.DirectorySeparatorChar.ToString() + "description.txt";
			BuildProperties properties = new BuildProperties();
			if (!File.Exists(path))
			{
				return properties;
			}
			if (File.Exists(path2))
			{
				properties.description = File.ReadAllText(path2);
			}
			string[] array = File.ReadAllLines(path);
			foreach (string text in array)
			{
				if (!string.IsNullOrWhiteSpace(text))
				{
					int num = text.IndexOf('=');
					string text2 = text.Substring(0, num).Trim();
					string text3 = text.Substring(num + 1).Trim();
					if (text3.Length != 0)
					{
						uint num2 = <PrivateImplementationDetails>.ComputeStringHash(text2);
						if (num2 <= 1310244050u)
						{
							if (num2 <= 844722965u)
							{
								if (num2 <= 398089822u)
								{
									if (num2 != 289463891u)
									{
										if (num2 == 398089822u)
										{
											if (text2 == "side")
											{
												if (!Enum.TryParse<ModSide>(text3, true, out properties.side))
												{
													throw new Exception("side is not one of (Both, Client, Server, NoSync): " + text3);
												}
											}
										}
									}
									else if (text2 == "noCompile")
									{
										properties.noCompile = (text3.ToLower() == "true");
									}
								}
								else if (num2 != 598549679u)
								{
									if (num2 == 844722965u)
									{
										if (text2 == "sortAfter")
										{
											properties.sortBefore = BuildProperties.ReadList(text3).ToArray<string>();
										}
									}
								}
								else if (text2 == "weakReferences")
								{
									properties.weakReferences = BuildProperties.ReadList(text3).Select(new Func<string, BuildProperties.ModReference>(BuildProperties.ModReference.Parse)).ToArray<BuildProperties.ModReference>();
								}
							}
							else if (num2 <= 933909843u)
							{
								if (num2 != 901380689u)
								{
									if (num2 == 933909843u)
									{
										if (text2 == "includePDB")
										{
											properties.includePDB = (text3.ToLower() == "true");
										}
									}
								}
								else if (text2 == "dllReferences")
								{
									properties.dllReferences = BuildProperties.ReadList(text3).ToArray<string>();
								}
							}
							else if (num2 != 1181855383u)
							{
								if (num2 == 1310244050u)
								{
									if (text2 == "includeSource")
									{
										properties.includeSource = (text3.ToLower() == "true");
									}
								}
							}
							else if (text2 == "version")
							{
								properties.version = new Version(text3);
							}
						}
						else if (num2 <= 2781863564u)
						{
							if (num2 <= 1677043273u)
							{
								if (num2 != 1333443158u)
								{
									if (num2 == 1677043273u)
									{
										if (text2 == "buildIgnore")
										{
											properties.buildIgnores = (from s in text3.Split(new char[]
											{
												','
											})
											select s.Trim().Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar) into s
											where s.Length > 0
											select s).ToArray<string>();
										}
									}
								}
								else if (text2 == "author")
								{
									properties.author = text3;
								}
							}
							else if (num2 != 2381632922u)
							{
								if (num2 == 2781863564u)
								{
									if (text2 == "hideCode")
									{
										properties.hideCode = (text3.ToLower() == "true");
									}
								}
							}
							else if (text2 == "sortBefore")
							{
								properties.sortAfter = BuildProperties.ReadList(text3).ToArray<string>();
							}
						}
						else if (num2 <= 3475483701u)
						{
							if (num2 != 3278728922u)
							{
								if (num2 == 3475483701u)
								{
									if (text2 == "homepage")
									{
										properties.homepage = text3;
									}
								}
							}
							else if (text2 == "hideResources")
							{
								properties.hideResources = (text3.ToLower() == "true");
							}
						}
						else if (num2 != 3489752662u)
						{
							if (num2 != 4097972693u)
							{
								if (num2 == 4242114625u)
								{
									if (text2 == "modReferences")
									{
										properties.modReferences = BuildProperties.ReadList(text3).Select(new Func<string, BuildProperties.ModReference>(BuildProperties.ModReference.Parse)).ToArray<BuildProperties.ModReference>();
									}
								}
							}
							else if (text2 == "languageVersion")
							{
								if (!int.TryParse(text3, out properties.languageVersion))
								{
									throw new Exception("languageVersion not an int: " + text3);
								}
								if (properties.languageVersion < 4 || properties.languageVersion > 6)
								{
									throw new Exception("languageVersion (" + properties.languageVersion + ") must be between 4 and 6");
								}
							}
						}
						else if (text2 == "displayName")
						{
							properties.displayName = text3;
						}
					}
				}
			}
			List<string> list = properties.RefNames(true).ToList<string>();
			if (list.Count != list.Distinct<string>().Count<string>())
			{
				throw new Exception("Duplicate mod/weak reference");
			}
			properties.sortAfter = (from dep in properties.RefNames(true)
			where !properties.sortBefore.Contains(dep)
			select dep).Concat(properties.sortAfter).Distinct<string>().ToArray<string>();
			return properties;
		}

		// Token: 0x06000F61 RID: 3937 RVA: 0x00402E8C File Offset: 0x0040108C
		internal byte[] ToBytes()
		{
			byte[] result;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
				{
					if (this.dllReferences.Length != 0)
					{
						binaryWriter.Write("dllReferences");
						BuildProperties.WriteList<string>(this.dllReferences, binaryWriter);
					}
					if (this.modReferences.Length != 0)
					{
						binaryWriter.Write("modReferences");
						BuildProperties.WriteList<BuildProperties.ModReference>(this.modReferences, binaryWriter);
					}
					if (this.weakReferences.Length != 0)
					{
						binaryWriter.Write("weakReferences");
						BuildProperties.WriteList<BuildProperties.ModReference>(this.weakReferences, binaryWriter);
					}
					if (this.sortAfter.Length != 0)
					{
						binaryWriter.Write("sortAfter");
						BuildProperties.WriteList<string>(this.sortAfter, binaryWriter);
					}
					if (this.sortBefore.Length != 0)
					{
						binaryWriter.Write("sortBefore");
						BuildProperties.WriteList<string>(this.sortBefore, binaryWriter);
					}
					if (this.author.Length > 0)
					{
						binaryWriter.Write("author");
						binaryWriter.Write(this.author);
					}
					binaryWriter.Write("version");
					binaryWriter.Write(this.version.ToString());
					if (this.displayName.Length > 0)
					{
						binaryWriter.Write("displayName");
						binaryWriter.Write(this.displayName);
					}
					if (this.homepage.Length > 0)
					{
						binaryWriter.Write("homepage");
						binaryWriter.Write(this.homepage);
					}
					if (this.description.Length > 0)
					{
						binaryWriter.Write("description");
						binaryWriter.Write(this.description);
					}
					if (this.noCompile)
					{
						binaryWriter.Write("noCompile");
					}
					if (!this.hideCode)
					{
						binaryWriter.Write("!hideCode");
					}
					if (!this.hideResources)
					{
						binaryWriter.Write("!hideResources");
					}
					if (this.includeSource)
					{
						binaryWriter.Write("includeSource");
					}
					if (this.includePDB)
					{
						binaryWriter.Write("includePDB");
					}
					if (this.editAndContinue)
					{
						binaryWriter.Write("editAndContinue");
					}
					if (this.side != ModSide.Both)
					{
						binaryWriter.Write("side");
						binaryWriter.Write((byte)this.side);
					}
					if (ModLoader.beta)
					{
						binaryWriter.Write("beta");
					}
					binaryWriter.Write("");
				}
				result = memoryStream.ToArray();
			}
			return result;
		}

		// Token: 0x06000F62 RID: 3938 RVA: 0x004030FC File Offset: 0x004012FC
		internal static BuildProperties ReadModFile(TmodFile modFile)
		{
			BuildProperties buildProperties = new BuildProperties();
			buildProperties.hideCode = true;
			buildProperties.hideResources = true;
			byte[] file = modFile.GetFile("Info");
			if (file.Length == 0)
			{
				return buildProperties;
			}
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(file)))
			{
				string text = binaryReader.ReadString();
				while (text.Length > 0)
				{
					if (text == "dllReferences")
					{
						buildProperties.dllReferences = BuildProperties.ReadList(binaryReader).ToArray<string>();
					}
					if (text == "modReferences")
					{
						buildProperties.modReferences = BuildProperties.ReadList(binaryReader).Select(new Func<string, BuildProperties.ModReference>(BuildProperties.ModReference.Parse)).ToArray<BuildProperties.ModReference>();
					}
					if (text == "weakReferences")
					{
						buildProperties.weakReferences = BuildProperties.ReadList(binaryReader).Select(new Func<string, BuildProperties.ModReference>(BuildProperties.ModReference.Parse)).ToArray<BuildProperties.ModReference>();
					}
					if (text == "sortAfter")
					{
						buildProperties.sortAfter = BuildProperties.ReadList(binaryReader).ToArray<string>();
					}
					if (text == "sortBefore")
					{
						buildProperties.sortBefore = BuildProperties.ReadList(binaryReader).ToArray<string>();
					}
					if (text == "author")
					{
						buildProperties.author = binaryReader.ReadString();
					}
					if (text == "version")
					{
						buildProperties.version = new Version(binaryReader.ReadString());
					}
					if (text == "displayName")
					{
						buildProperties.displayName = binaryReader.ReadString();
					}
					if (text == "homepage")
					{
						buildProperties.homepage = binaryReader.ReadString();
					}
					if (text == "description")
					{
						buildProperties.description = binaryReader.ReadString();
					}
					if (text == "noCompile")
					{
						buildProperties.noCompile = true;
					}
					if (text == "!hideCode")
					{
						buildProperties.hideCode = false;
					}
					if (text == "!hideResources")
					{
						buildProperties.hideResources = false;
					}
					if (text == "includeSource")
					{
						buildProperties.includeSource = true;
					}
					if (text == "includePDB")
					{
						buildProperties.includePDB = true;
					}
					if (text == "editAndContinue")
					{
						buildProperties.editAndContinue = true;
					}
					if (text == "side")
					{
						buildProperties.side = (ModSide)binaryReader.ReadByte();
					}
					if (text == "beta")
					{
						buildProperties.beta = true;
					}
					text = binaryReader.ReadString();
				}
			}
			return buildProperties;
		}

		// Token: 0x06000F63 RID: 3939 RVA: 0x00403364 File Offset: 0x00401564
		internal bool ignoreFile(string resource)
		{
			return this.buildIgnores.Any((string fileMask) => this.FitsMask(resource, fileMask));
		}

		// Token: 0x06000F64 RID: 3940 RVA: 0x0040339C File Offset: 0x0040159C
		private bool FitsMask(string fileName, string fileMask)
		{
			string pattern = "^" + Regex.Escape(fileMask.Replace(".", "__DOT__").Replace("*", "__STAR__").Replace("?", "__QM__")).Replace("__DOT__", "[.]").Replace("__STAR__", ".*").Replace("__QM__", ".") + "$";
			return new Regex(pattern, RegexOptions.IgnoreCase).IsMatch(fileName);
		}

		// Token: 0x040012C2 RID: 4802
		internal string[] dllReferences = new string[0];

		// Token: 0x040012C3 RID: 4803
		internal BuildProperties.ModReference[] modReferences = new BuildProperties.ModReference[0];

		// Token: 0x040012C4 RID: 4804
		internal BuildProperties.ModReference[] weakReferences = new BuildProperties.ModReference[0];

		// Token: 0x040012C5 RID: 4805
		internal string[] sortAfter = new string[0];

		// Token: 0x040012C6 RID: 4806
		internal string[] sortBefore = new string[0];

		// Token: 0x040012C7 RID: 4807
		internal string[] buildIgnores = new string[0];

		// Token: 0x040012C8 RID: 4808
		internal string author = "";

		// Token: 0x040012C9 RID: 4809
		internal Version version = new Version(1, 0);

		// Token: 0x040012CA RID: 4810
		internal string displayName = "";

		// Token: 0x040012CB RID: 4811
		internal bool noCompile;

		// Token: 0x040012CC RID: 4812
		internal bool hideCode;

		// Token: 0x040012CD RID: 4813
		internal bool hideResources;

		// Token: 0x040012CE RID: 4814
		internal bool includeSource;

		// Token: 0x040012CF RID: 4815
		internal bool includePDB;

		// Token: 0x040012D0 RID: 4816
		internal bool editAndContinue;

		// Token: 0x040012D1 RID: 4817
		internal bool beta;

		// Token: 0x040012D2 RID: 4818
		internal int languageVersion = 4;

		// Token: 0x040012D3 RID: 4819
		internal string homepage = "";

		// Token: 0x040012D4 RID: 4820
		internal string description = "";

		// Token: 0x040012D5 RID: 4821
		internal ModSide side;

		// Token: 0x02000181 RID: 385
		internal struct ModReference
		{
			// Token: 0x06000F66 RID: 3942 RVA: 0x0000E6EC File Offset: 0x0000C8EC
			public ModReference(string mod, Version target)
			{
				this.mod = mod;
				this.target = target;
			}

			// Token: 0x06000F67 RID: 3943 RVA: 0x0000E6FC File Offset: 0x0000C8FC
			public override string ToString()
			{
				if (!(this.target == null))
				{
					return this.mod + "@" + this.target;
				}
				return this.mod;
			}

			// Token: 0x06000F68 RID: 3944 RVA: 0x004034C4 File Offset: 0x004016C4
			public static BuildProperties.ModReference Parse(string spec)
			{
				string[] array = spec.Split(new char[]
				{
					'@'
				});
				if (array.Length == 1)
				{
					return new BuildProperties.ModReference(array[0], null);
				}
				if (array.Length > 2)
				{
					throw new Exception("Invalid mod reference: " + spec);
				}
				BuildProperties.ModReference result;
				try
				{
					result = new BuildProperties.ModReference(array[0], new Version(array[1]));
				}
				catch
				{
					throw new Exception("Invalid mod reference: " + spec);
				}
				return result;
			}

			// Token: 0x040012D6 RID: 4822
			public string mod;

			// Token: 0x040012D7 RID: 4823
			public Version target;
		}
	}
}
